package com.dawn.cloud.pos.drive.sdk;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Looper;

import com.orhanobut.logger.Logger;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

/**
 * Created by yyh on 2018/6/20.
 */

public class BmpSdk extends BroadcastReceiver {

    //正在连接
    private static final int STATUS_CONNECTING = 1;
    //连接失败
    private static final int STATUS_ERROR = 2;
    //连接成功
    private static final int STATUS_CONNECT = 3;
    //返回消息
    private static final int STATUS_BACK = 4;

    //选择设备地址
    private String serverAddress;

    //蓝牙
    private BluetoothAdapter mBluetoothAdapter;
    private List<BluetoothDevice> mDeviceList;
    private BluetoothDevice mDevice;
    //线程类
    private ClientThread mClientThread;
    private ReadThread mReadThread;
    // 蓝牙客户端socket
    private BluetoothSocket mSocket;

    //是否连接服务
    private boolean mSocketConnect;

    //是否连接服务
    private String mConnect;

    //服务器端数据
    private String serverData;

    //客户端日志
    private String clientLog;

    //配对蓝牙名称
    private String bluetoothName = "";

    public BmpSdk() {
        mDeviceList = new ArrayList<>();
        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        setmBluetoothAdapter(mBluetoothAdapter);
        //判断蓝牙功能呢是否存在
        if (mBluetoothAdapter == null) {
            Logger.d("无蓝牙模块");
            setClientLog("无蓝牙模块");
            return;
        }
    }

    /**
     * 打开蓝牙
     *
     * @return
     */
    public boolean open(String bluetoothName) {
        this.bluetoothName = bluetoothName;
        boolean isOpen = false;
        //判断蓝牙是否打开
        if (mBluetoothAdapter.isEnabled()) {
            Logger.d("蓝牙已经打开了");
            setClientLog("蓝牙已经打开了");
            isOpen = true;
        } else {
            //强制打开蓝牙
            isOpen = mBluetoothAdapter.enable();
        }
        return isOpen;
    }

    /**
     * 搜索蓝牙设备
     */
    public void discovery() {
        if (mBluetoothAdapter.isDiscovering()) {
            mBluetoothAdapter.cancelDiscovery();
        } else {
            mBluetoothAdapter.startDiscovery();
        }
    }

    /**
     * 蓝牙发送消息
     *
     * @param data
     */
    public void sendMessage(String data) {
        setServerData("");
        if (mSocket == null) {
            Logger.d("mSocket没有连接");
            setClientLog("mSocket没有连接");
            return;
        }
        try {
            Logger.d("发出的指令是:" + data);
            OutputStream os = mSocket.getOutputStream();
            os.write(data.getBytes("utf-8"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if (BluetoothDevice.ACTION_FOUND.equals(action)) {
            // 获得设备信息
            BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
            Logger.d("蓝牙设备个数:" + mDeviceList.size() + "\nName:" + device.getName() + ",Address:" + device.getAddress());
            setClientLog("\n蓝牙设备个数:" + mDeviceList.size() + "\nName:" + device.getName() + ",Address:" + device.getAddress());

            // 如果绑定的状态不一样(判断给定地址下的device是否已经配对)
//                if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
            mDeviceList.add(device);
//                    mySpinnerAdapter.notifyDataSetChanged();
//                }
            String name = device.getName();
            if (bluetoothName.equals(device.getName())) {
                mBluetoothAdapter.cancelDiscovery();
                serverAddress = device.getAddress();
                mDevice = mBluetoothAdapter.getRemoteDevice(device.getAddress());
                //打开客户端线程
                mClientThread = new ClientThread();
                mClientThread.start();
            }
            // 如果搜索完成了
        } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
//                mBluetoothAdapter.cancelDiscovery();
//                if (mDeviceList.size() > 0) {
//                    for (BluetoothDevice device : mDeviceList) {
//                        if ("HUAWEI P20".equals(device.getName())) {
//                            serverAddress = device.getAddress();
//                            mDevice = mBluetoothAdapter.getRemoteDevice(device.getAddress());
//                            //打开客户端线程
//                            mClientThread = new ClientThread();
//                            mClientThread.start();
//                        }
//                    }
//                }
        }
    }

    // 客户端连接线程
    private class ClientThread extends Thread {
        public void run() {
            Looper.prepare();
            try {
                mSocket = mDevice.createInsecureRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));
                Logger.d("正在连接服务:" + serverAddress);
                setClientLog("正在连接服务:" + serverAddress);
                try {
                    mSocket.connect();
                } catch (Exception e) {
                    Method m = mDevice.getClass().getMethod("createRfcommSocket", new Class[]{int.class});
                    //       mSocket = mDevice.createInsecureRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));
                    mSocket = (BluetoothSocket) m.invoke(mDevice, 2);
                    mSocket.getRemoteDevice();
                    mSocket.connect();
                }
                setmSocketConnect(true);
                setmConnect("ok");
//                mSocketConnect = true;
                Logger.d("已经连接上服务！可以发送信息:" + serverAddress);
                Logger.d("mSocketConnect = " + getmSocketConnect());
                setClientLog("已经连接上服务！可以发送信息:" + serverAddress);
                //TODO 启动接受数据  服务端返回数据
                mReadThread = new ReadThread();
                mReadThread.start();

                //注意子线程不能刷新
                //UIViewRootImpl$CalledFromWrongThreadException:
                //ll_bluetooth.setVisibility(View.VISIBLE);
            } catch (Exception e) {
                Logger.d("连接服务端异常:" + e.getMessage());
                setClientLog("连接服务端异常:" + e.getMessage());
            }
            Looper.loop();
        }
    }

    // 从服务端返回值
    private class ReadThread extends Thread {
        public void run() {
            byte[] buffer = new byte[1024];
            int bytes;
            InputStream is = null;
            try {
                is = mSocket.getInputStream();
                while (true) {
                    if ((bytes = is.read(buffer)) > 0) {
                        byte[] buf_data = new byte[bytes];
                        for (int i = 0; i < bytes; i++) {
                            buf_data[i] = buffer[i];
                        }
                        setServerData(new String(buf_data));
                        Logger.d("服务端返回数据:" + serverData);
                        setClientLog("连接服务端异常:" + serverData);
                    }
                }
            } catch (IOException e1) {
                e1.printStackTrace();
            } finally {
                try {
                    is.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
        }
    }

    //停止客户端连接
    public void shutdownClient() {
        new Thread() {
            public void run() {
                if (mClientThread != null) {
                    mClientThread.interrupt();
                    mClientThread = null;
                }
                if (mReadThread != null) {
                    mReadThread.interrupt();
                    mReadThread = null;
                }
                if (mSocket != null) {
                    try {
                        mSocket.close();
                        Logger.d("mSocket close");
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    mSocket = null;
                }
            }
        }.start();
    }


    public String getServerAddress() {
        return serverAddress;
    }

    public void setServerAddress(String serverAddress) {
        this.serverAddress = serverAddress;
    }

    public BluetoothAdapter getmBluetoothAdapter() {
        return mBluetoothAdapter;
    }

    public void setmBluetoothAdapter(BluetoothAdapter mBluetoothAdapter) {
        this.mBluetoothAdapter = mBluetoothAdapter;
    }

    public List<BluetoothDevice> getmDeviceList() {
        return mDeviceList;
    }

    public void setmDeviceList(List<BluetoothDevice> mDeviceList) {
        this.mDeviceList = mDeviceList;
    }

    public BluetoothDevice getmDevice() {
        return mDevice;
    }

    public void setmDevice(BluetoothDevice mDevice) {
        this.mDevice = mDevice;
    }

    public ClientThread getmClientThread() {
        return mClientThread;
    }

    public void setmClientThread(ClientThread mClientThread) {
        this.mClientThread = mClientThread;
    }

    public ReadThread getmReadThread() {
        return mReadThread;
    }

    public void setmReadThread(ReadThread mReadThread) {
        this.mReadThread = mReadThread;
    }

    public BluetoothSocket getmSocket() {
        return mSocket;
    }

    public void setmSocket(BluetoothSocket mSocket) {
        this.mSocket = mSocket;
    }

    public boolean getmSocketConnect() {
        return mSocketConnect;
    }

    public void setmSocketConnect(boolean mSocketConnect) {
        this.mSocketConnect = mSocketConnect;
    }

    public String getServerData() {
        return serverData;
    }

    public void setServerData(String serverData) {
        this.serverData = serverData;
    }

    public String getClientLog() {
        return clientLog;
    }

    public void setClientLog(String clientLog) {
        this.clientLog = clientLog;
    }

    public String getmConnect() {
        return mConnect;
    }

    public void setmConnect(String mConnect) {
        this.mConnect = mConnect;
    }
}
